﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "GnufBase.h"
#include "GnufItemEvents.h"
#include "GnufPallet.h"
#include "GnufObjectPtr.h"
#include "FilePath.h"

namespace gnuf
{
    class Toolbar;
    class Pallet;
    class SearchBox;
    class TreeBoard;
    class Block;
    class IPalletEventHandler;

    enum class EPalletFootButton : std::uint8_t
    {
        eApply = 0,
        eOK,
        eCancle
    };
    class GNUF_BASE_EXPORT HotKeyConfigurationPallet final
        : public IItemEventHandler
        , public IPalletEventHandler
    {
        friend class QtHotKeyConfigurationPallet;
    public:
        typedef std::map<std::wstring, std::wstring> Hotkeys;
        static HotKeyConfigurationPallet* get();
        virtual ~HotKeyConfigurationPallet();

    public:
        void setDisableModifiedHotkeyIdOnce(const std::set<std::wstring>& hotkeyIds) {
            m_setUnableModifiedHotKeyIds = hotkeyIds;
        }
        void show(bool synchronously);
        void close();

        Toolbar* toolBar() { return m_toolbar.get(); }

    protected:
        //Inherits from IItemEventHandler
        virtual void onClicked(Item *) override;
        virtual void onTreeItemChanged(QTreeWidgetItem *item, int column) override;
        virtual void onHovered(Item *, bool hovered, void * qtWidget) override;

        //Inherits from IPalletEventHandler
        virtual void onHeaderButtonClicked(gnuf::Pallet* pPallet) override;
        virtual bool onFooterButtonClicked(gnuf::Pallet* pPallet) override;
        virtual void onRefreshStyle() override;
        virtual bool onKeyEvent(Pallet *, IPalletEventHandler::EKey) override;

    private:
        HotKeyConfigurationPallet();
        void initialize();
        void initializeControl();
        void initializeData();
        void setCustomSetting();

        void onImportButtonClicked();
        void onExportButtonClicked();
        void onRestoreButton();


        /// \brief When the modification to hotkeys is discarded, fetch hotkeys from hotkey manager.
        void fetchHotkeysFromManager();

#ifndef _GNUF_WIP_TEST_HOTKEY_MANAGER_2_LOGIC_
        bool checkMofiHotKey(const TreeNode* node, const std::wstring& oldKey, std::wstring& newKey);
#endif
        /// \brief Set the flag of dirty hotkey.
        /// If none hotkey has been modified since last persistence, than set the flag as false.
        /// Otherwise, set the flag as true.
        /// \see updateHotkeyCache markIfHotkeyDirty
        void setHotkeyDirty(bool bDirty) { m_bHotkeyDirty = bDirty; }
        
        /// \brief In pallet, we will cache a map of hotkey id to hotkey value, this function is aim to update this map.
        /// The map is used to determine whether there is any dirty in hotkeys.
        void updateHotkeyCache();

        /// \brief After a modification to hotkey, mark dirty flag if it was dirty.
        /// \param idOfChangedHotkey the id of hotkey which has been modified just now.
        /// \param newValueOfChangedHotkey new value of hotkey which has been modified just now.
        void markIfHotkeyDirty(const std::wstring& idOfChangedHotkey, const std::wstring& newValueOfChangedHotkey);

        /// \brief When an overall change take place to hotkeys(such as reset, import), mark as dirty if it was.
        void markIfHotkeyDirty();

        /// \brief The ability of apply button need to be update as dirty state.
        void refreshApplyButtonAbility();
    private:
        gcmp::OwnerPtr<QtHotKeyConfigurationPallet> m_nativePallet;
        gcmp::OwnerPtr<Pallet> m_pallet;
        gcmp::OwnerPtr<Toolbar> m_toolbar;
        Block*   m_pSettingBlock;
        gnuf::ObjectWeakPtr<gnuf::ButtonEx> m_pImportButton;
        gnuf::ObjectWeakPtr<gnuf::ButtonEx> m_pExportButton;
        gnuf::ObjectWeakPtr<gnuf::ButtonEx> m_pRestoreButton;
        gcmp::WeakPtr<gnuf::TreeBoard> m_tree;
        gcmp::WeakPtr<gnuf::SearchBox> m_searchBox;
        bool m_bHotkeyDirty = false;
        Hotkeys m_mapIdToValue;
        std::set<std::wstring> m_setUnableModifiedHotKeyIds;
        gcmp::FilePath m_lastImportfilePath;
        static HotKeyConfigurationPallet s_instance;
    };
}
